/****************************************************************************
Copyright (c) 2020-2024 Qualcomm Technologies International, Ltd.
%%version

FILE NAME
    mcp.h
    
DESCRIPTION
    Header file for the Media Control Profile (MCP) library.
*/

/*!
@file    mcp.h
@brief   Header file for the GATT MCP library.

        This file provides documentation for the GATT MCP library
        API (library name: mcp).
*/

#ifndef MCP_H
#define MCP_H

#include "csr_bt_gatt_prim.h"
#include "service_handle.h"
#include "gatt_mcs_client.h"
#include "mcp_mcs_common.h"
#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
#include "gatt_ots_client.h"
#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */

#define MCP_PROFILE_PRIM             (SYNERGY_EVENT_BASE + MCP_PRIM)

/*!
    @brief MCP handles.

*/
typedef struct
{
    uint16                  mcsInstCount;
    GattMcsClientDeviceData *mcsHandle;
}McpHandles;

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
typedef struct
{
    uint16                otsInstCount;
    GattOtscDeviceData    *otsHandle;
}McpOtsHandles;
#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */

/*!
    @brief Initialisation parameters.

*/
typedef struct
{
    McpConnectionId cid;
}McpInitData;

/*!
    \brief MCP status code type.
*/
typedef uint16                           McpStatus;

#define MCP_STATUS_SUCCESS              ((McpStatus) 0x00)  /*!> Request was a success*/
#define MCP_STATUS_OTS_FAILED           ((McpStatus) 0x01)  /*!> Request was a Ots failure*/
#define MCP_STATUS_NOT_SUPPORTED        ((McpStatus) 0x02) /*!>  Not supported by remote device*/
#define MCP_STATUS_MEDIAPLAYER_INACTIVE ((McpStatus) 0x03) /*!>  Media Player in remote device is inactive*/
#define MCP_STATUS_COMMAND_INCOMPLETE   ((McpStatus) 0x04)  /*!> Command requested could not be completed*/
#define MCP_STATUS_DISCOVERY_ERR        ((McpStatus) 0x05)  /*!> Error in discovery of one of the services*/
#define MCP_STATUS_FAILED               ((McpStatus) 0x06)  /*!> Request has failed*/
#define MCP_STATUS_IN_PROGRESS          ((McpStatus) 0x07)  /*!> Request in progress*/
#define MCP_STATUS_INVALID_PARAMETER    ((McpStatus) 0x08)  /*!> Invalid parameter was supplied*/
#define MCP_STATUS_BUSY                 ((McpStatus) 0x09)  /*!> Request is busy*/
#define MCP_STATUS_INVALID_PDU          ((McpStatus) 0x0A)  /*!> Invalid parameter was supplied for SCP and response came for invalid PDU */


/*! @brief Enumeration of messages a client task may receive from the profile library.
 */

typedef uint16                                   McpMessageId;

#define MCP_INIT_CFM                            ((McpMessageId) 0x01)
#define MCP_DESTROY_CFM                         ((McpMessageId) 0x02)
#define MCP_MCS_TERMINATE_CFM                   ((McpMessageId) 0x03)
#define MCP_NTF_IND                             ((McpMessageId) 0x04)
#define MCP_NTF_CFM                             ((McpMessageId) 0x05)
#define MCP_SET_MEDIA_PLAYER_ATTRIBUTE_CFM      ((McpMessageId) 0x06)
#define MCP_SET_MEDIA_CONTROL_POINT_CFM         ((McpMessageId) 0x07)

#define MCP_GET_MEDIA_PLAYER_NAME_CFM          ((McpMessageId) 0x08)
#define MCP_GET_MEDIA_PLAYER_ICON_URL_CFM      ((McpMessageId) 0x09)
#define MCP_GET_TRACK_TITLE_CFM                ((McpMessageId) 0x0A)
#define MCP_GET_TRACK_DURATION_CFM             ((McpMessageId) 0x0B)
#define MCP_GET_TRACK_POSITION_CFM             ((McpMessageId) 0x0C)
#define MCP_GET_PLAYBACK_SPEEED_CFM            ((McpMessageId) 0x0D)
#define MCP_GET_SEEKING_SPEED_CFM              ((McpMessageId) 0x0E)
#define MCP_GET_PLAYING_ORDER_CFM              ((McpMessageId) 0x0F)
#define MCP_GET_PLAYING_ORDER_SUPPORTED_CFM    ((McpMessageId) 0x10)
#define MCP_GET_MEDIA_STATE_CFM                ((McpMessageId) 0x11)
#define MCP_GET_SUPPORTED_OPCODES_CFM          ((McpMessageId) 0x12)
#define MCP_GET_CONTENT_CONTROL_ID_CFM         ((McpMessageId) 0x13)

#define MCP_MEDIA_PLAYER_NAME_IND               ((McpMessageId) 0x14)
#define MCP_TRACK_CHANGED_IND                   ((McpMessageId) 0x15)
#define MCP_TRACK_TITLE_IND                     ((McpMessageId) 0x16)
#define MCP_TRACK_DURATION_IND                  ((McpMessageId) 0x17)
#define MCP_TRACK_POSITION_IND                  ((McpMessageId) 0x18)
#define MCP_PLAYBACK_SPEEED_IND                 ((McpMessageId) 0x19)
#define MCP_SEEKING_SPEED_IND                   ((McpMessageId) 0x1A)
#define MCP_PLAYING_ORDER_IND                   ((McpMessageId) 0x1B)
#define MCP_MEDIA_STATE_IND                     ((McpMessageId) 0x1C)
#define MCP_SUPPORTED_OPCODES_IND               ((McpMessageId) 0x1D)

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
#define MCP_MEDIA_PLAYER_ICON_OBJ_ID_CFM        ((McpMessageId) 0x1E)
#define MCP_CURRENT_TRACK_SEGMENTS_OBJ_ID_CFM   ((McpMessageId) 0x1F)
#define MCP_CURRENT_TRACK_OBJ_ID_CFM            ((McpMessageId) 0x20)
#define MCP_NEXT_TRACK_OBJ_ID_CFM               ((McpMessageId) 0x21)
#define MCP_CURRENT_GROUP_OBJ_ID_CFM            ((McpMessageId) 0x22)
#define MCP_PARENT_GROUP_OBJ_ID_CFM             ((McpMessageId) 0x23)
#define MCP_SEARCH_RESULT_OBJ_ID_CFM            ((McpMessageId) 0x24)

#define MCP_INIT_OPT_SERVICES_CFM               ((McpMessageId) 0x25)
#define MCP_OTS_IND_CFM                         ((McpMessageId) 0x26)
#define MCP_GET_OBJECT_CONTENTS_BY_OBJ_ID_CFM   ((McpMessageId) 0x27)
#define MCP_START_DISCOVER_OBJECT_CFM           ((McpMessageId) 0x28)
#define MCP_STOP_DISCOVER_OBJECT_CFM            ((McpMessageId) 0x29)
#define MCP_GET_CURRENT_MEDIA_OBJECT_TYPE_CFM   ((McpMessageId) 0x2A)
#define MCP_GET_CURRENT_MEDIA_OBJECT_SIZE_CFM   ((McpMessageId) 0x2B)
#define MCP_GET_CURRENT_MEDIA_OBJECT_ID_CFM     ((McpMessageId) 0x2C)
#define MCP_GET_CURRENT_MEDIA_OBJECT_PROP_CFM   ((McpMessageId) 0x2D)
#define MCP_GET_CURRENT_MEDIA_OBJECT_NAME_CFM   ((McpMessageId) 0x2E)
#define MCP_ABORT_OTS_PROCEDURE_CFM             ((McpMessageId) 0x2F)
#define MCP_SET_MEDIA_OBJECT_CONTENT_CFM        ((McpMessageId) 0x30)

#define MCP_DISCOVER_OBJECT_TYPE_IND            ((McpMessageId) 0x31)
#define MCP_DISCOVER_OBJECT_SIZE_IND            ((McpMessageId) 0x32)
#define MCP_DISCOVER_OBJECT_ID_IND              ((McpMessageId) 0x33)
#define MCP_DISCOVER_OBJECT_PROP_IND            ((McpMessageId) 0x34)
#define MCP_DISCOVER_OBJECT_NAME_IND            ((McpMessageId) 0x35)
#define MCP_OBJECT_CHANGED_IND                  ((McpMessageId) 0x36)

#define MCP_CURRENT_TRACK_OBJ_ID_IND            ((McpMessageId) 0x37)
#define MCP_NEXT_TRACK_OBJ_ID_IND               ((McpMessageId) 0x38)
#define MCP_CURRENT_GROUP_OBJ_ID_IND            ((McpMessageId) 0x39)
#define MCP_PARENT_GROUP_OBJ_ID_IND             ((McpMessageId) 0x3A)
#define MCP_SEARCH_RESULTS_OBJ_ID_IND           ((McpMessageId) 0x3B)
#define MCP_SET_SEARCH_CONTROL_POINT_CFM        ((McpMessageId) 0x3C)


/* Defined values for Optional Services, as on new services will come need to add bit mask for those here */
typedef uint8 McpOptionalServices;
#define MCP_OPTIONAL_SERVICE_INVALID          ((McpOptionalServices)0x00)
#define MCP_OPTIONAL_SERVICE_OTS              ((McpOptionalServices)0x01)
#define MCP_OPTIONAL_SERVICE_ALL              ((McpOptionalServices)0xFF)
#endif

/*!
    @brief Profile library message sent as a result of calling the McpInitReq API.
*/
typedef struct
{
    McpMessageId        id;
    McpStatus          status;          /*! Status of the initialisation attempt*/
    McpProfileHandle   prflHndl;        /*! MCP profile handle */
    uint16             mcsInstCount;
    ServiceHandle     *mcsSrvcHandle;
} McpInitCfm;

/*!
    @brief Profile library message sent as a result of calling the McpDestroyReq API.

    This message will send at first with the value of status of MCP_STATUS_IN_PROGRESS.
    Another MCP_DESTROY_CFM message will be sent with the final status (success or fail),
    after MCP_MCS_TERMINATE_CFM has been received.
*/
typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;     /*! MCP profile handle*/
    McpStatus         status;       /*! Status of the initialisation attempt*/
} McpDestroyCfm;

/*!
    @brief Profile library message sent as a result of calling the McpDestroyReq API and
           of the receiving of the GATT_MCS_CLIENT_TERMINATE_CFM message from the gatt_mcs_client
           library.
*/
typedef struct
{
    McpMessageId                    id;
    McpProfileHandle               prflHndl;          /*! MCP profile handle*/
    McpStatus                      status;            /*! Status of the termination attempt*/
    GattMcsClientDeviceData        mcsHandle;         /*! Characteristic handles of MCS*/
    bool                           moreToCome;        /*! TRUE if more of this message will come, FALSE otherwise*/
} McpMcsTerminateCfm;

/*! @brief Contents of the McpNtfInd message that is sent by the library,
    as a result of setting notifications on the server for selected characteristics.
    This will have results for individual characteristics set notification attempt.
 */
typedef struct
{
    McpMessageId              id;
    McpProfileHandle         prflHndl;     /*! MCP profile handle*/
    ServiceHandle            srvcHndl;     /*! Reference handle for the instance */
    MediaPlayerAttribute     charac;      /* Characteristic name */
    McpStatus                status;       /*! Status of the setting attempt */
} McpNtfInd;

/*! @brief Contents of the McpNtfCfm message that is sent by the library,
    as a result of setting notifications on the server for selected characteristics.
    This marks the end of the register for notification request.
 */
typedef struct
{
    McpMessageId              id;
    McpProfileHandle         prflHndl;     /*! MCP profile handle*/
    ServiceHandle            srvcHndl;     /*! Reference handle for the instance */
    McpStatus                status;
} McpNtfCfm;

/*! @brief Contents of the McpCommonWriteMcsCfm message that is sent by the library,
    as a result of writing on the requested characteristic on the server.
 */
typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;    /*! MCP profile handle*/
    ServiceHandle     srvcHndl;    /*! Reference handle for the instance */
    MediaPlayerAttribute charac;      /* Characteristic name */
    McpStatus          status;      /*! Status of the writing attempt */
} McpSetMediaPlayerAttributeCfm;

/*! @brief Contents of the McpSetMediaControlPointCfm message that is sent by the library,
    as a result of writing on Media Control Point characteristic on the server.
 */
typedef struct
{
    McpMessageId         id;
    McpProfileHandle    prflHndl;     /*! MCP profile handle*/
    ServiceHandle       srvcHndl;     /*! Reference handle for the instance */
    McpStatus           status;       /*! Status of the reading attempt */
    GattMcsOpcode       op;
} McpSetMediaControlPointCfm;

/*! @brief Contents of the McpGetMediaPlayerNameCfm message that is sent by the library,
    as response to a read of the Media Player Name.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus         status;           /*! Status of the reading attempt */
    uint16            len;              /*! Value length */
    uint8*            name;            /*! Value */
} McpGetMediaPlayerNameCfm;

/*! @brief Contents of the McpGetMediaPlayerIconUrlCfm message that is sent by the library,
    as response to a read of the Media Player Icon Url.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    uint16            len;              /*! Value length */
    uint8*            iconUrl;          /*! Value */
} McpGetMediaPlayerIconUrlCfm;


/*! @brief Contents of the McpGetTrackTitleCfm message that is sent by the library,
    as response to a read of the Title Track.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    uint16            len;              /*! Value length */
    uint8*            trackTitle;       /*! Value */
} McpGetTrackTitleCfm;

/*! @brief Contents of the McpGetTrackDurationCfm message that is sent by the library,
    as response to a read of the Title Duration.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    int32             trackDuration;    /*! Value */
} McpGetTrackDurationCfm;

/*! @brief Contents of the McpGetTrackPositionCfm message that is sent by the library,
    as response to a read of the Title Position.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    int32             trackPosition;    /*! Value */
} McpGetTrackPositionCfm;

/*! @brief Contents of the McpGetPlaybackSpeedCfm message that is sent by the library,
    as response to a read of the Playback Speed.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    int8              playbackSpeed;    /*! Value */
} McpGetPlaybackSpeedCfm;

/*! @brief Contents of the McpGetSeekingSpeedCfm message that is sent by the library,
    as response to a read of the Seeking Speed.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    int8              seekingSpeed;     /*! Value */
} McpGetSeekingSpeedCfm;

/*! @brief Contents of the McpGetPlayinOrderCfm message that is sent by the library,
    as response to a read of the Playing Order.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    uint8             playingOrder;     /*! Value */
} McpGetPlayinOrderCfm;

/*! @brief Contents of the McpGetPlayinOrderSupportedCfm message that is sent by the library,
    as response to a read of the Supported Playing Order.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;                  /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                  /*! Reference handle for the instance */
    McpStatus          status;                    /*! Status of the reading attempt */
    uint16            playingOrderSupported;     /*! Value */
} McpGetPlayinOrderSupportedCfm;

/*! @brief Contents of the McpGetMediaStateCfm message that is sent by the library,
    as response to a read of the Media State.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;                  /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                  /*! Reference handle for the instance */
    McpStatus          status;                    /*! Status of the reading attempt */
    uint8             mediaState;                /*! Value */
} McpGetMediaStateCfm;

/*! @brief Contents of the McpGetOpcodesSupportedCfm message that is sent by the library,
    as response to a read of the Media Control Point Opcodes supported.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;                  /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                  /*! Reference handle for the instance */
    McpStatus          status;                    /*! Status of the reading attempt */
    uint32            opcodesSupported;          /*! Value */
} McpGetOpcodesSupportedCfm;

/*! @brief Contents of the McpGetContentControlIdCfm message that is sent by the library,
    as response to a read of the Content Control Id.
*/

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;                  /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                  /*! Reference handle for the instance */
    McpStatus          status;                    /*! Status of the reading attempt */
    uint8              ccid;                      /*! Value */
} McpGetContentControlIdCfm;

/*! @brief Contents of the McpMediaPlayerNameNotifInd message that is sent by the library,
    as a result of a notification of a Media Player Name.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    uint16            len;              /*! Value length */
    uint8*            name;             /*! Value */
} McpMediaPlayerNameInd;

/*! @brief Contents of the McpTrackChangedNotifInd message that is sent by the library,
    as a result of a notification when track is changed.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
} McpTrackChangedInd;

/*! @brief Contents of the McpTrackTitleNotifInd message that is sent by the library,
    as a result of  notification of Title track.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    uint16            len;              /*! Value length */
    uint8*            trackTitle;       /*! Value */
} McpTrackTitleInd;

/*! @brief Contents of the McpTrackDurationNotifInd message that is sent by the library,
    as a result of a notification of Duration of currently playing track.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    int32             trackDuration;    /*! Value */
} McpTrackDurationInd;

/*! @brief Contents of the McpTrackPositionNotifInd message that is sent by the library,
    as a result of a notification of Position of currently playing track(when media state is other 
    than PLAY).
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    int32             trackPosition;    /*! Value */
} McpTrackPositionInd;

/*! @brief Contents of the McpPlaybackSpeedNotifInd message that is sent by the library,
    as a result of a notification when Playback speed changes.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    int8              playbackSpeed;    /*! Value */
} McpPlaybackSpeedInd;

/*! @brief Contents of the McpSeekingSpeedNotifInd message that is sent by the library,
    as a result of a notification when seeking speed changes.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    McpStatus          status;           /*! Status of the reading attempt */
    int8              seekingSpeed;     /*! Value */
} McpSeekingSpeedInd;

/*! @brief Contents of the McpPlayinOrderNotifInd message that is sent by the library,
    as a result of a notification when playing order changes.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;         /*! MCP profile handle*/
    ServiceHandle     srvcHndl;         /*! Reference handle for the instance */
    uint8             playingOrder;     /*! Value */
} McpPlayingOrderInd;

/*! @brief Contents of the McpMediaStateNotifInd message that is sent by the library,
    as a result of a notification of a Media State change.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;                  /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                  /*! Reference handle for the instance */
    uint8             mediaState;                /*! Value */
} McpMediaStateInd;

/*! @brief Contents of the McpOpcodesSupportedNotifInd message that is sent by the library,
    as a result of a notification when supported opcode changes.
 */

typedef struct
{
    McpMessageId       id;
    McpProfileHandle  prflHndl;                  /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                  /*! Reference handle for the instance */
    uint32            opcodesSupported;          /*! Value */
} McpOpcodesSupportedInd;

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE
/*!
    @brief Profile library message sent as a result of calling the McpInitOptServices API.
*/
typedef struct
{
    McpOptionalServices optService;
    ServiceHandle       serviceHndl;
}OptServiceInfo;

typedef struct
{
    McpMessageId        id;
    McpProfileHandle    prflHndl;            /*! MCP profile handle */
    McpStatus           status;              /*! Status of the initialisation attempt*/
    uint8               optServiceInfoCount; /*! number of optional services */
    OptServiceInfo      *optSerInfo;         /*! Optional service information */
} McpInitOptServicesCfm;

/*! @brief Contents of the McpGetMediaPlayerAttribute message that is sent by the library,
    as response to a read object Id.
 */
typedef struct
{
    McpMessageId      id;
    McpProfileHandle  prflHndl;                     /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                     /*! Reference handle for the instance */
    GattOtscObjectId  objectId;                     /*! Object Id Value */
    McpStatus         status;                       /*! Status of the reading attempt */
    uint16            resultSupplier;               /*! result code is sent by MCP or OTS */
} McpGetObjectIdCfm;

/*! @brief Contents of the McpOtsIndCfm message that is sent by the library,
    as a result of setting Indication on the server for object changed characteristics.
    This marks the end of the register for Indication request.
 */
typedef struct
{
    McpMessageId             id;
    McpProfileHandle         prflHndl;           /*! MCP profile handle*/
    ServiceHandle            srvcHndl;           /*! Reference handle for the instance */
    McpStatus                status;
    uint16                   resultSupplier;     /*! result code is sent by MCP or OTS */
} McpOtsIndCfm;

/*! @brief Contents of the McpGetObjectContentsByObjId message that is sent by the library,
    as response to a read current object content.
 */
typedef struct
{
    McpMessageId      id;
    McpProfileHandle  prflHndl;                     /*! MCP profile handle*/
    ServiceHandle     srvcHndl;                     /*! MCS client instance requested */
    McpStatus         status;                       /*! Status of the reading attempt */
    uint16            resultSupplier;               /*! result code is sent by MCP or OTS */
    uint16            dataLen;                      /*! Length of the data to be read/consumed   */
    uint8*            data;                         /*! Data pointer which holds either
                                                        the Source of the object's content in Stream [for VM platform]
                                                        or
                                                        the actual object contents [For non-VM platforms].
                                                        Application must consume and free the data as explained.
                                                        Refer to McpGetObjectContentsByObjIdReq() for more info */
    bool              moreToCome;                   /*! More messages to come if TRUE            */
} McpGetObjectContentsByObjIdCfm;

typedef struct
{
    McpMessageId          id;
    McpProfileHandle      prflHndl;              /*! MCP profile handle */
    ServiceHandle         srvcHndl;              /*! MCS client instance requested */
    uint16                valueLength;           /*! Metadata value length */
    uint8                 *value;                /*! Metadata value */
} McpGetObjectMetadataCommonInd;

typedef McpGetObjectMetadataCommonInd McpDiscoverObjectTypeInd;
typedef McpGetObjectMetadataCommonInd McpDiscoverObjectSizeInd;
typedef McpGetObjectMetadataCommonInd McpDiscoverObjectIdInd;
typedef McpGetObjectMetadataCommonInd McpDiscoverObjectPropInd;
typedef McpGetObjectMetadataCommonInd McpDiscoverObjectNameInd;

typedef McpGetObjectMetadataCommonInd McpCurrentTrackObjIdChangedInd;
typedef McpGetObjectMetadataCommonInd McpNextTrackObjIdChangedInd;
typedef McpGetObjectMetadataCommonInd McpCurrentGroupObjIdChangedInd;
typedef McpGetObjectMetadataCommonInd McpParentGroupObjIdChangedInd;
typedef McpGetObjectMetadataCommonInd McpSearchResultObjIdChangedInd;


typedef struct
{
    McpMessageId                id;
    McpProfileHandle            prflHndl;              /*! MCP profile handle */
    ServiceHandle               srvcHndl;              /*! MCS client instance requested */
    McpStatus                   status;                /*! Status */
    uint16                      resultSupplier;        /*! result code is sent by MCP or OTS */ 
} McpDiscoverObjectCommonCfm;

typedef McpDiscoverObjectCommonCfm McpStartDiscoverObjectCfm;
typedef McpDiscoverObjectCommonCfm McpStopDiscoverObjectCfm;

/*! @brief Contents of the McpCurrentMediaObjectAttributeReq message that is sent by the library,
    as response to a read current media metadata procedure.
Note:
   Byte Transmission Order of All object characteristics used with the least significant octet first (i.e., little endian).
   The least significant octet is identified in MCP/OTS specification as well as in the characteristic definitions */
typedef struct
{
    McpMessageId          id;
    McpProfileHandle      prflHndl;              /*! MCP profile handle */
    ServiceHandle         srvcHndl;              /*! MCS client instance requested */
    McpStatus             status;                /*! Status of the reading attempt */
    uint16                resultSupplier;        /*! result code is sent by MCP or OTS */
    uint16                valueLength;           /*!  Metadata value length */
    uint8                 *value;                /*! Metadata value */
} McpGetObjectMetadataCommonCfm;

typedef McpGetObjectMetadataCommonCfm McpGetCurrentMediaObjectNameCfm;
typedef McpGetObjectMetadataCommonCfm McpGetCurrentMediaObjectTypeCfm;
typedef McpGetObjectMetadataCommonCfm McpGetCurrentMediaObjectSizeCfm;
typedef McpGetObjectMetadataCommonCfm McpGetCurrentMediaObjectIdCfm;
typedef McpGetObjectMetadataCommonCfm McpGetCurrentMediaObjectPropCfm;


/*! @brief Contents of the McpAbortOtsProcedureReq message that is sent by the library,
    as response to an abort object read req.
 */
typedef struct
{
    McpMessageId          id;
    McpProfileHandle      prflHndl;              /*! MCP profile handle */
    ServiceHandle         srvcHndl;              /*! MCS client instance requested */
    McpStatus             status;                /*! Status of the abort attempt */
    uint16                resultSupplier;        /*! Result code is sent by MCP or OTS */
} McpAbortOtsProcedureCfm;

/*! @brief Object Changed occurred in remote.
 */
typedef struct
{
    McpMessageId              id;
    McpProfileHandle          prflHndl;          /*! MCP profile handle */
    ServiceHandle             srvcHndl;          /*! MCS client instance requested */
    GattOtscObjectId          objectId;          /*! Object ID on which change occurred */
    GattOtscDeviceType        modifier;          /*! Device[Another Client/Server] which made the change */
    GattOtscObjectChangeType  changeType;        /*! Kind of change occurred at server */
} McpObjectChangedInd;

/*! @brief Contents of the McpSetSearchControlPointCfm message that is sent by the library,
    as a result of writing on Search Control Point characteristic on the server.
 */
typedef struct
{
    McpMessageId         id;
    McpProfileHandle    prflHndl;     /*! MCP profile handle*/
    ServiceHandle       srvcHndl;     /*! Reference handle for the instance */
    McpStatus           status;       /*! Status of the reading attempt */
} McpSetSearchControlPointCfm;
#endif

/*!
    @brief Initialises the Gatt MCP Library.

    NOTE: This interface need to be invoked for every new gatt connection that wishes to use
    the Gatt MCP library.

    @param appTask           The Task that will receive the messages sent from this profile library
    @param clientInitParams   Initialisation parameters
    @param deviceData         MCS service handles
    NOTE: A MCP_INIT_CFM with McpStatus code equal to MCP_STATUS_IN_PROGRESS will be received as indication that
          the profile library initialisation started. Once completed MCP_INIT_CFM will be received with a McpStatusT
          that indicates the result of the initialisation.
*/
void McpInitReq(AppTask appTask,
                McpInitData *clientInitParams,
                McpHandles  *deviceData);

/*!
    @brief When a GATT connection is removed, the application must remove all profile and
    client service instances that were associated with the connection.
    This is the clean up routine as a result of calling the McpInitReq API.

    @param profileHandle The Profile handle.

    NOTE: A MCP_DESTROY_CFM with McpStatus code equal to MCP_STATUS_IN_PROGRESS will be received as indication
          that the profile library destroy started. Post that for each MCS instance a MCP_MCS_TERMINATE_CFM will
          be received. Once completed MCP_DESTROY_CFM will be received with a McpStatus that indicates the
          result of the destroy.
*/
void McpDestroyReq(McpProfileHandle profileHandle);

/*!
    @brief This API is used to write the client characteristic configuration of MCS related
    characteristics on a remote device, to enable notifications with the server.
    An error will be returned if the server does not support notifications.

    @param profileHandle       The Profile handle.
    @param mcsHandle           The MCS instance handle.
    @param characType          Bitmask of MCS characteristics.
    @param notifValue          Bitmask to enable/disable respective characteristics CCCD.

    NOTE: MCP_NTF_CFM message will be sent to the registered application Task.
          After calling this API, Application shall wait for the MCP_NTF_CFM to come before
          calling any other API.

*/
void McpRegisterForNotificationReq(McpProfileHandle profileHandle, ServiceHandle mcsHandle, MediaPlayerAttributeMask characType, uint32 notifValue);

/*!
    @brief This API is used to read the value of requested characteristic.

    @param profileHandle       The Profile handle.
    @param mcsHandle           The MCS instance handle.
    @param charac               Characteristic whose value has to be read.

    NOTE: A MCP_GET_XXXXXXX_CFM message will be sent to the registered application Task.

*/
void McpGetMediaPlayerAttribute(McpProfileHandle profileHandle, ServiceHandle mcsHandle, MediaPlayerAttribute charac);

/*!
    @brief This API is used to change the value of a characteristic.

    @param profileHandle       The Profile handle.
    @param mcsHandle           The MCS instance handle.
    @param charac               Characteristic whose value has to be written.
    @param len                  Length of the value.
    @param val                  Value to be written of the characteristic.

    NOTE: A MCP_SET_MEDIA_PLAYER_ATTRIBUTE_CFM message will be sent to the registered application Task.

*/
void McpSetMediaPlayerAttribute(McpProfileHandle profileHandle, ServiceHandle mcsHandle, MediaPlayerAttribute charac, uint16 len, uint8 *val);

/*!
    @brief This API is used to write the Media Control point characteristic in order to execute
           the opcode related operation on the server device.

    @param profileHandle       The Profile handle.
    @param mcsHandle           The MCS instance handle.
    @param op                   Opcode selected.
    @param val                  Value of parameter to be sent along the write req.

    NOTE: A MCP_SET_MEDIA_CONTROL_POINT_CFM message will be sent to the registered application Task.
          For opcodes which doesn't support additional parameters, if some value is sent it will be ignored.

*/
void McpSetMediaControlPoint(McpProfileHandle profileHandle, ServiceHandle mcsHandle, GattMcsOpcode op, int32 val);

/*!
    @brief This API is used to retrieve the Media Control point characteristic and descriptor handles stored
           by the profile library during discovery procedure.

    @param profileHandle       The Profile handle.
    @param mcsHandle           The MCS instance handle.

    @return GattMcsClientDeviceData : The structure containing characteristic and descriptor handles info.
            If the handles are not found or any other error happens in the process, NULL will be returned.

    NOTE: This is not a message passing based API, the handles, if found, will be returned immediately to the app.

*/
GattMcsClientDeviceData *McpGetMediaPlayerAttributeHandles(McpProfileHandle profileHandle, ServiceHandle mcsHandle);

#ifndef EXCLUDE_GATT_OTS_CLIENT_MODULE

/*!
    @brief This API is used to write the Search Control point characteristic in order to execute
           the filter related operation on the server device.

    @param profileHandle       The Profile handle.
    @param mcsHandle           The MCS instance handle.
    @param valueLength         Value Length of parameter to be sent along the write req.
    @param value               Value of parameter to be sent along the write req.

    NOTE1:Application need to frame a LTV strcuture for the SCP filter as per spec as below:

    -------------------------------------------------------
     Type Value     | Name          | Parameter Description
    -------------------------------------------------------
      0x01          | Track Name    |    UTF-8 string
      0x02          | Artist Name   |    UTF-8 string
      0x03          | Album Name    |    UTF-8 string
      0x04          | Group Name    |    UTF-8 string
      0x05          | Earliest Year |    UTF-8 string
      0x06          | Latest Year   |    UTF-8 string
      0x07          | Genre         |    UTF-8 string
      0x08          | Only Tracks   |    None
    -------------------------------------------------------
    Each Row forms an LTV which application need to construct for the desired filter e.g.
    For setting the filters for track name and artist name application need to construct LTV's for each one of them
    And then feed it to the interface.
    Type value(McpScpOpcode) is defined in mcp_mcs_common.h interface which application may use it 
    While constructing LTV filters.

    NOTE2: A MCP_SET_SEARCH_CONTROL_POINT_CFM message will be sent to the registered application Task.
*/
void McpSetSearchControlPoint(McpProfileHandle profileHandle, ServiceHandle mcsHandle, uint32 valueLength, uint8* value);

/*!
    @brief This API is used to set the client profile characteristic and
           descriptor handles stored by the profile library during OTS discovery
           procedure.

    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.

    @param gattOtsData OTS handles which got discovered as part of gatt service discovery.

    @return bool

    Note: This Interface shall be used by the application before McpInitOptServices procedure.
    OTS handles value will set in MCP profile if the mcsHandles are valid.
    If App is setting the mcsHandles to NULL or this API is not invoked, MCP will perform the full discovery procedure.
*/
bool  McpSetOtsHandles(McpProfileHandle profileHandle, ServiceHandle mcsHandle, const McpOtsHandles *gattOtsData);

/*!
    @brief Initialises the optional services e.g. OTS/Other future services within MCP library
    Application recieves MCP_INIT_OPT_SERVICES_CFM when this message is called.

    @param profileHandle       MCP Profile handle.
    @param optServices         Bit mask of the optional services which APP is interested
                               Refer McpOptionalServices for available bit mask in mcp.h
                               For the defined optional services.

    Note: This Interface shall be used by the application post McpInitReq procedure.
*/
void McpInitOptServicesReq(McpProfileHandle profileHandle, McpOptionalServices optServices);

/*!
    @brief This API is used to retrieve the OTS characteristic and descriptor handles stored
           by the OTS profile library during discovery procedure.

    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.

    @return GattOtscDeviceData*  The structure containing characteristic and descriptor handles info.
                                 If the handles are not found or any other error happens in the process,NULL will be returned.

    NOTE: This is not a message passing based API, the handles, if found, will be returned immediately to the application.

*/
GattOtscDeviceData* McpGetOtsAttributeHandles(McpProfileHandle profileHandle, ServiceHandle mcsHandle);

/*!
    @brief This API is used to write the client characteristic configuration of OTS related
    characteristics on a remote device, to enable indications with the server to recieve object changed indication
    An error will be returned if the server does not support indications.

    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.
    @param characType          Bitmask of OTS Characteristics type to be configured, refer gatt_ots_client.h for values.

    NOTE: MCP_OTS_IND_CFM message will be sent to the registered application Task.
          After calling this API, Application shall wait for the MCP_OTS_IND_CFM to come before
          calling any other API.

*/
void McpRegisterForObjChangedIndReq(McpProfileHandle profileHandle,
                                 ServiceHandle mcsHandle,
                                 GattOtscCharacValuesMask charValsMask);

/*!
    @brief This API is used to get the ots object contents for a give object ID.

    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.

    @param GattOtscObjectId    Object id stream of size 6 octets(object size as per OTS spec).

    Note1:
    Byte Transmission Order of GattOtscObjectId used with the least significant octet first (i.e., little endian)
    The least significant octet is identified in MCP/OTS specification as well as in the characteristic definitions.
    @param readObject          When Application will set to TRUE, MCP will read the object contents and 
                               When Set to FALSE, MCP will make this object to be current Object Only.

    @param readOffset          Offset from where application wanted to read the object contents,
                              Currently Profile supports full read only(Offset implementation is left for future).
   
    @param objectLength        Length of the object which application wanted to read,
                              Currently Profile supports full read only(length implementation is left for future).

    Note2:
    These 2 parameters are reserved for future purpose, which currently application need to pass default values as
         shown in the table(MCP library will ignore these values).
           |parameters        | default values         |
           |----------------------------------  -------|
           | readOffset       | 0x00                   |
           | objectLength     | 0x00                   |

    NOTE3:
    MCP_GET_OBJECT_CONTENTS_BY_OBJ_ID_CFM message will be sent to the registered application Task.
         OTS spec mandates to have only one LECOC channel to get opened for object transfer,
         MCP specification recommend application to send only one request to read object content at a time.
         If Application will trigger multiple request to read object contents, OTS may reject the req with
         status as GATT_OTSC_RESULT_CODE_OPERATION_FAILED.
         If Application wants to abort current object contents read and wants to read new object contents, application
         may call McpAbortOtsProcedureReq() procedure.

    NOTE4:
    Application must read the object content from the "data" pointer it receives
    in "McpGetObjectContentsByObjIdCfm" message,.and frees it as explained below.

    In below ex, "cfm" is shown as the pointer of "McpGetObjectContentsByObjIdCfm" message.

    [For VM platform]
     1. "data" pointer is not the actual object content instead it is the "Source"
        of the object's content present in stream. So it needs to be first typecasted to "Source" type.

        Source dataSource = (Source) cfm->data;

     2. Map the above dataSource to the data pointer(sourcePtr in below ex.) now
        which does hold the actual object's content.

        const uint8 *dataPtr = SourceMap(dataSource);

     3. Read the object content from data pointer (dataPtr) for the data length
        sent through "dataLen" or copy those to the local place holder for parsing.

     4. Once object content is read/consumed, free these by dropping from stream.

        SourceDrop(dataSource, cfm->dataLen);

    [For non-VM platform]
     "data" pointer holds the actual object's content, so no special handling required.
      Make sure application frees the "data" pointer once it is read/consumed by calling
      CsrPmemFree().
*/
void McpGetObjectContentsByObjIdReq(McpProfileHandle profileHandle,
                             ServiceHandle mcsHandle,
                             const GattOtscObjectId objId,
                             bool readObject,
                             uint16 readOffset,      /* RFU */
                             uint32 objectLength);    /* RFU */

/*!
    @brief This API is used to get the ots oject Metadata for current selected object.

    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.

    @param objeMetadataType    objectMetadataType, refer McpObjectMetadataType for the values in mcp_mcs_common.h
  
   NOTE: MCP_GET_CURRENT_MEDIA_OBJECT_XXX_CFM message will be sent to the registered application Task.
         This API should be invoked post McpGetObjectContentsByObjId as first OTS need to make select object
         Procedure to make object as current object according to OTS specficiation and then only application
         Can call this API to get object metadata.

*/
void McpGetCurrentMediaObjMetadataReq(McpProfileHandle profileHandle,
                                    ServiceHandle mcsHandle,
                                    McpObjectMetadataType objMetadataType);

/*!
    @brief This API is used to disocver All oject Metadata(objMetadataType) from remote.

    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.
    @param objeMetadataType    objectMetadataType, refer McpObjectMetadataType for the values in mcp.h

    @param     filters         Filter bitmask of max three filters to be applied at server
    @param     nameInfo        Name information for which filter to be applied
    @param     dateInfo        Date information for which filter to be applied
    @param     objSizeInfo     Object size information for which filter to be applied
    @param     objectUuid      Obect's Gatt UUID type for which filter to be applied

   Note1: 
   Above 5 parameters are are reserved for future purpose.
   Application need to pass default values as shown in the table(MCP library will ignore these values).

            |parameteres   | default values                |
            |----------------------------------- ----------|
            | filters      | GATT_OTSC_FILTER_NONE         |
            | nameInfo     | NULL                          |
            | dateInfo     | NULL                          |
            | objSizeInfo  | NULL                          |
            | objectUuid   | OTSC_INVALID_OBJECT_UUID      |
            |----------------------------------------------|


   NOTE2:
   Application will recieve MCP_DISCOVER_OBJECT_XXX_IND till all the object traversal followed by MCP_START_DISCOVER_OBJECT_CFM.
   Application need to stop other OTS procedure e.g. McpGetObjectContentsByObjIdReq/McpGetCurrentMediaObjMetadataReq 
   During McpStartDiscoverAllObjReq Procedure as internally Disocvery will move current object from first to last and 
   Read the Metadata which OTS spec mandates.
   Application will recieve MCP_STATUS_BUSY when McpStartDiscoverAllObjReq is in progress and
   Application called McpGetObjectContentsByObjIdReq/McpGetCurrentMediaObjMetadataReq.

*/
void McpStartDiscoverAllObjReq(McpProfileHandle profileHandle,
                               ServiceHandle mcsHandle,
                               McpObjectMetadataType objMetadataType,
                               GattOtscObjectFilters         filters,          /* RFU */
                               GattOtscFilterByNameInfo      *nameInfo,        /* RFU */
                               GattOtscFilterByDateInfo      *dateInfo,        /* RFU */
                               GattOtscFilterByObjSizeInfo   *objSizeInfo,     /* RFU */
                               CsrBtUuid                     objectUuid);      /* RFU */
/*!
    @brief This API is used to stop oject discovery when Application is no more intrested for futher objects information.

    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.

   NOTE: Application will recieve MCP_DISCOVER_OBJECT_XXX_IND, MCP_START_DISCOVER_OBJECT_CFM 
         And MCP_STOP_DISCOVER_OBJECT_CFM message will be sent to the registered application Task 
         When called during in middle of McpStartDiscoverAllObjReq().
*/
void McpStopDiscoverObjectsReq(McpProfileHandle profileHandle,
                               ServiceHandle mcsHandle);

/*!
    @brief This API is used to abort the current on going object content read procedure.
    @param profileHandle       MCP Profile handle.
    @param mcsHandle           MCS instance handle.

    NOTE: MCP_OTS_ABORT_CFM message will be sent to the registered application Task.

*/
void McpAbortOtsProcedureReq(McpProfileHandle profileHandle,
                                      ServiceHandle mcsHandle);

#endif /* EXCLUDE_GATT_OTS_CLIENT_MODULE */
#endif /* MCP_H */
